package com.shababeach.travel.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.shababeach.travel.dto.LoginResponse;
import com.shababeach.travel.dto.WxLoginRequest;
import com.shababeach.travel.entity.User;
import com.shababeach.travel.repository.UserRepository;
import com.shababeach.travel.service.WxService;
import com.shababeach.travel.util.JwtUtil;
import com.shababeach.travel.util.WxDecryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Slf4j
@Service
public class WxServiceImpl implements WxService {

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RestTemplate restTemplate;
    
    @Value("${wx.miniapp.appid}")
    private String appid;
    
    @Value("${wx.miniapp.secret}")
    private String secret;
    
    private static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Override
    public LoginResponse wxLogin(WxLoginRequest wxLoginRequest) {
        // 获取微信登录凭证
        String code = wxLoginRequest.getCode();
        String encryptedData = wxLoginRequest.getEncryptedData();
        String iv = wxLoginRequest.getIv();
        
        log.info("收到微信登录请求，code: {}", code);
        
        try {
            // 调用微信API获取openid和session_key
            String url = WX_LOGIN_URL + "?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
            log.info("请求微信接口: {}", url);
            
            String response = restTemplate.getForObject(url, String.class);
            log.info("微信接口返回: {}", response);
            JSONObject jsonObject = JSONObject.parseObject(response);
            
            // 检查是否包含错误码
            if (jsonObject.containsKey("errcode")) {
                Integer errcode = jsonObject.getInteger("errcode");
                String errmsg = jsonObject.getString("errmsg");
                log.error("微信登录失败 errcode: {}, errmsg: {}", errcode, errmsg);
                
                // 40029是无效的code错误，在开发环境下使用模拟数据
                if (errcode == 40029) {
                    log.info("开发环境下使用模拟数据");
                    return handleDevLogin(code, encryptedData, iv);
                }
                
                throw new RuntimeException("微信登录失败: " + errmsg);
            }
            
            String openid = jsonObject.getString("openid");
            String sessionKey = jsonObject.getString("session_key");
            log.info("获取到openid: {}, sessionKey: {}", openid, sessionKey);
            
            try {
                // 解密用户信息
                String decryptedData = WxDecryptUtil.decrypt(encryptedData, sessionKey, iv);
                log.info("解密后的用户信息: {}", decryptedData);
                
                // 解析解密后的用户信息
                JSONObject decryptedUserInfo = JSONObject.parseObject(decryptedData);
                
                // 查询或创建用户
                User user = findOrCreateUser(openid, decryptedUserInfo);
                
                // 生成JWT token
                String token = jwtUtil.generateToken(user.getId().toString());
                
                // 构建登录响应
                LoginResponse loginResponse = new LoginResponse();
                loginResponse.setToken(token);
                
                // 构建用户信息
                Map<String, Object> userInfo = new HashMap<>();
                userInfo.put("userId", user.getId().toString());
                userInfo.put("nickName", user.getNickName());
                userInfo.put("avatarUrl", user.getAvatarUrl());
                userInfo.put("gender", user.getGender());
                userInfo.put("visitCount", user.getVisitCount());
                userInfo.put("likeCount", user.getLikeCount());
                userInfo.put("favoriteCount", user.getFavoriteCount());
                
                loginResponse.setUserInfo(userInfo);
                log.info("登录成功，返回数据: {}", loginResponse);
                
                return loginResponse;
            } catch (Exception e) {
                log.error("解密用户信息失败", e);
                // 如果解密失败，使用默认用户信息
                User user = findOrCreateUser(openid, new JSONObject());
                String token = jwtUtil.generateToken(user.getId().toString());
                
                LoginResponse loginResponse = new LoginResponse();
                loginResponse.setToken(token);
                
                Map<String, Object> userInfo = new HashMap<>();
                userInfo.put("userId", user.getId().toString());
                userInfo.put("nickName", user.getNickName());
                userInfo.put("avatarUrl", user.getAvatarUrl());
                userInfo.put("gender", user.getGender());
                userInfo.put("visitCount", user.getVisitCount());
                userInfo.put("likeCount", user.getLikeCount());
                userInfo.put("favoriteCount", user.getFavoriteCount());
                
                loginResponse.setUserInfo(userInfo);
                return loginResponse;
            }
        } catch (Exception e) {
            log.error("微信登录异常", e);
            throw new RuntimeException("微信登录失败: " + e.getMessage());
        }
    }
    
    /**
     * 开发环境下处理模拟登录
     */
    private LoginResponse handleDevLogin(String code, String encryptedData, String iv) {
        // 使用code的后6位作为模拟的openid
        String mockOpenid = "dev_" + code.substring(Math.max(0, code.length() - 6));
        log.info("使用模拟openid: {}", mockOpenid);
        
        // 创建模拟用户信息
        JSONObject mockUserInfo = new JSONObject();
        mockUserInfo.put("nickName", "测试用户");
        mockUserInfo.put("avatarUrl", "/static/logo.png");
        mockUserInfo.put("gender", 0);
        mockUserInfo.put("city", "广州");
        mockUserInfo.put("province", "广东");
        mockUserInfo.put("country", "中国");
        mockUserInfo.put("language", "zh_CN");
        
        // 查询或创建用户
        User user = findOrCreateUser(mockOpenid, mockUserInfo);
        
        // 生成JWT token
        String token = jwtUtil.generateToken(user.getId().toString());
        
        // 构建登录响应
        LoginResponse loginResponse = new LoginResponse();
        loginResponse.setToken(token);
        
        // 构建用户信息
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getId().toString());
        userInfo.put("nickName", user.getNickName());
        userInfo.put("avatarUrl", user.getAvatarUrl());
        userInfo.put("gender", user.getGender());
        userInfo.put("visitCount", user.getVisitCount());
        userInfo.put("likeCount", user.getLikeCount());
        userInfo.put("favoriteCount", user.getFavoriteCount());
        
        loginResponse.setUserInfo(userInfo);
        log.info("开发环境登录成功，返回数据: {}", loginResponse);
        
        return loginResponse;
    }
    
    /**
     * 查找或创建用户
     */
    private User findOrCreateUser(String openid, JSONObject userInfo) {
        Optional<User> userOptional = userRepository.findByOpenid(openid);
        
        if (userOptional.isPresent()) {
            // 用户已存在，更新用户信息
            User user = userOptional.get();
            updateUserInfo(user, userInfo);
            return userRepository.save(user);
        } else {
            // 创建新用户
            User user = new User();
            user.setOpenid(openid);
            updateUserInfo(user, userInfo);
            return userRepository.save(user);
        }
    }
    
    /**
     * 更新用户信息
     */
    private void updateUserInfo(User user, JSONObject userInfo) {
        if (userInfo == null || userInfo.isEmpty()) {
            // 如果没有用户信息，设置默认值
            if (user.getNickName() == null) user.setNickName("微信用户");
            if (user.getAvatarUrl() == null) user.setAvatarUrl("/static/logo.png");
            if (user.getGender() == null) user.setGender(0);
            return;
        }
        
        // 安全获取用户信息，如果字段不存在则保留原值或使用默认值
        String nickName = userInfo.getString("nickName");
        if (nickName != null && !nickName.isEmpty()) {
            user.setNickName(nickName);
        } else if (user.getNickName() == null) {
            user.setNickName("微信用户");
        }
        
        String avatarUrl = userInfo.getString("avatarUrl");
        if (avatarUrl != null && !avatarUrl.isEmpty()) {
            user.setAvatarUrl(avatarUrl);
        } else if (user.getAvatarUrl() == null) {
            user.setAvatarUrl("/static/logo.png");
        }
        
        Integer gender = userInfo.getInteger("gender");
        if (gender != null) {
            user.setGender(gender);
        } else if (user.getGender() == null) {
            user.setGender(0);
        }
        
        // 其他字段可以为空
        user.setCity(userInfo.getString("city"));
        user.setProvince(userInfo.getString("province"));
        user.setCountry(userInfo.getString("country"));
        user.setLanguage(userInfo.getString("language"));
    }
} 